<?php
/**
 * food option
 */
class food_option_model extends CI_Model {
    private $error = array();
    private $is_valid_schema = false;
    
	/**
	 * constructor to pre load database object
	 */
	function __construct()
	{
		parent::__construct();
		$this->load->database();
	}
    /**
     * @param string $food_option_category_id
     * @param int $size
     * @param int $offset
     * @param bool $encode_html
     * @return array food options
     */
	function get_option($food_option_category_id, $size=9999, $offset=0, $encode_html = true)
	{
		$options = array();
		$this->db->order_by("sequence", "id"); 
		/**
		 * if size is set, then apply it to the query, else get all available options
		 */
		$this->db->limit($size, $offset);
        
		//----------------------------------------------------------------------
		$this->db->where('food_option_category_id', $food_option_category_id);
		$query = $this->db->get('food_option');

        foreach ($query->result_array() as $row)
		{
            if($encode_html === true){
                $row['en_name'] = htmlentities($row['en_name'], ENT_QUOTES, "UTF-8");
                $row['ch_name'] = htmlentities($row['ch_name'], ENT_QUOTES, "UTF-8");
            }
    		$options[$row['id']] = $row;
		}
		return $options;
	}

    /**
     * create a new food option into database
     *
     * @param $category_id
     * @param $en_name
     * @param $ch_name
     * @param $sequence
     * @param $price
     *
     * @return array error
     */
	function create($category_id, $en_name, $ch_name, $sequence, $price)
	{
		$this->error = array('user' => array(), 'system' => array());

        // category id checking
        $this->load->model('food_option_category_model', 'food_option_category');
        $category = $this->food_option_category->read($category_id);
        if(array_key_exists('id', $category) === false){
            $this->error['system']['category_id'] = 'category id not exist';
        }

        // prepare data for validation and create
        $en_name = trim($en_name); $ch_name = trim($ch_name); $sequence = trim($sequence); $price = trim($price);

        //unique sequence check
        $condition = "food_option_category_id = '" . mysql_real_escape_string($category_id) .
                     "' AND sequence = '" . mysql_real_escape_string($sequence) . "'";
        if($this->_hit_count($condition) > 0){
            $this->error['user']['create_action'] = 'food category already exist with same sequence';
            return $this->error;
        }

        // validate data
		$this->_validate_schema($en_name, $ch_name, $sequence, $price);

        // insert it if valid, or return non-empty error;
        if(true === $this->is_valid_schema){
            $data = array(
                'food_option_category_id' => $category_id, 'en_name' => $en_name, 'ch_name' => $ch_name,
                'sequence' => $sequence, 'price' => $price
            );
            // create new food option now
            $this->db->insert('food_option', $data);
        }
        return $this->error;
	}
    /**
     * get one food option information
     *
     * @param int $id
     * @param bool $encode_html
     * @return array
     */
	function read($id, $encode_html = true)
	{
        $this->db->limit(1);
		$this->db->where('id', $id);
		$query = $this->db->get('food_option');
		$result = $query->row_array();

        if($encode_html){
            foreach($result as $key => $value){
                $result[$key] = htmlentities($value, ENT_QUOTES, "UTF-8");
            }
        }
        return $result;
	}

    /**
     * @param string $id
     * @param string $category_id
     * @param string $en_name
     * @param string $ch_name
     * @param string $sequence
     * @param string $price
     *
     * @return array error
     */
	function update($id, $category_id, $en_name, $ch_name, $sequence, $price)
	{
		$this->error = array('user' => array(), 'system' => array());

		/**
         * check database integrity in development
         */
        $condition = "id = '" . mysql_real_escape_string($id) . "'";
        if($this->_hit_count($condition) != 1){
            $this->error['system']['update_query'] = "update query hit is not exactly 1 row";
        }

        // prepare data for validation and create
        $en_name = trim($en_name); $ch_name = trim($ch_name); $sequence = trim($sequence); $price = trim($price);

        //unique sequence check, it is okay to update with same sequence in same category the row it updated agsint  
        $option = $this->read($id);
        $condition = "food_option_category_id = '" . mysql_real_escape_string($category_id) .
                     "' AND sequence = '" . mysql_real_escape_string($sequence) . "'";
        if($this->_hit_count($condition) > 0 && $sequence !== $option['sequence']){
            $this->error['user']['update_action'] = 'food category already exist with same sequence';
            return $this->error;
        }

        // validate data
		$this->_validate_schema($en_name, $ch_name, $sequence, $price);

        // update it if valid, or return non-empty error;
        if(true === $this->is_valid_schema){
            $data = array(
                'food_option_category_id' => $category_id, 'en_name' => $en_name, 'ch_name' => $ch_name,
                'sequence' => $sequence, 'price' => $price
            );
            // create new food option now
            $this->db->where("id", $id);
            $this->db->update('food_option', $data);
        }
        return $this->error;
	}
	/**
	 * delete food option
	 *
	 * @param int $id
	 * @return array error
	 */
	function delete($id)
	{
        $this->error = array('user' => array(), 'system' => array());
        /**
         * check database integrity in development, put in system error array
         */
        $condition = "id = '" . mysql_real_escape_string($id) . "'";
        if($this->_hit_count($condition) !== 1){
            $this->error['system']['delete_query'] = 'delete query hit is not exactly 1 row';
        }

        // ready to proceeding delete
		$this->db->where('id', $id);
		$this->db->delete('food_option');
        return $this->error;
	}
    /**
     * @param string $from_id
     * @param string $to_id
     * @return array
     */
    function swap($from_id, $to_id)
    {
        $this->error = array('user' => array(), 'system' => array());

        // prepare data
        $from_id = trim($from_id); $to_id = trim($to_id);

        // if in same place
        if($from_id === $to_id){
            $this->error['user']['swap_sql'] = "swap between same place disallowed";
            return $this->error;
        }
        // if in difference palce but have multiple hits, system tampered
        $condition = "id = '" . mysql_real_escape_string($from_id) . "'";
        $from = $this->_hit_count($condition);
        $condition = "id = '" . mysql_real_escape_string($to_id) . "'";
        $to = $this->_hit_count($condition);

        if($from !== 1 && $to !== 1){
            $this->error['system']['swap_query'] = 'swap query result in more than 2 rows, check database integrity';
        }

        // ready for swap now, get sequence (above tests ensure one hit)
        $from_food = $this->read($from_id);
        $to_food = $this->read($to_id);
        $this->db->where('id', $from_id);
        $this->db->update('food_option', array('sequence' => $to_food['sequence']));
        $this->db->where('id', $to_id);
        $this->db->update('food_option', array('sequence' => $from_food['sequence']));

        return $this->error;
    }

    /**
     * helper to determine how many rows exists in database with certain conditions
     * @param string $condition
     * @return int
     */
    private function _hit_count($condition){
        $result = $this->db->query("SELECT * FROM `food_option` WHERE " . $condition);
        return $result->num_rows();
    }

    /**
     * @param $en_name
     * @param $ch_name
     * @param $sequence
     * @param $price
     * 
     * @return void
     */
    private function _validate_schema($en_name, $ch_name, $sequence, $price)
    {
        // reset schema valid indicater
        $this->is_valid_scehma = false;
        $this->load->library('validation/validation_string');

        $user_error_intro_count = count($this->error['user']);

        // en_name 0 - 64 chars
        $this->validation_string->set_data($en_name)->max_length(64)->min_length(1);
        if(false === $this->validation_string->result()){
            $this->error['user']['en_name'] = "en name should have 1 - 64 characters";
		}

        // ch_name less than 64 chars
        $this->validation_string->set_data($ch_name)->max_length(64)->min_length(1);
        if(false === $this->validation_string->result()){
            $this->error['user']['ch_name'] = "ch name should have 1 - 64 characters";
		}

        // sequence less than 8 chars, in format combine digit and '-'
        $this->validation_string->set_data($sequence)->is_sequence();
        if(false === $this->validation_string->result()){
            $this->error['user']['sequence'] = "sequence should less than 8 chars, in format combine digit and - ";
		}

        $price_test = (float)$price;
        if($price_test < 0 || !is_numeric($price)){
            $this->error['user']['price'] = "price should not be negative double";
        }

        $user_error_outro_count = count($this->error['user']);

        if($user_error_intro_count === $user_error_outro_count){
            $this->is_valid_schema = true;
        }
        
    }
     
}

/* End of file food_option_model.php */
/* Location: ./system/application/models/food_option_model.php */
